package com.ld.control.business.queue.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ld.control.business.process.model.ProcessNodeExampleModel;
import com.ld.control.business.process.model.ProcessNodeParamExampleModel;
import com.ld.control.business.process.service.ProcessNodeExampleService;
import com.ld.control.business.process.service.ProcessNodeParamExampleService;
import com.ld.control.business.queue.mapper.PendingNodeQueueMapper;
import com.ld.control.business.queue.model.PendingNodeQueueModel;
import com.ld.control.business.queue.service.PendingNodeQueueService;
import com.ld.control.business.variable.service.VariableExampleService;
import com.ld.control.business.variable.vo.resp.VariableExampleValueResp;
import com.ld.control.common.NodeParamConstant;
import com.ld.control.sysenum.ProcessNodeNameEnum;
import com.ld.control.sysenum.TaskStatusEnum;
import com.ld.control.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用于放一些命令节点的待处理记录，如：delay、waitFor 服务实现类
 * </p>
 *
 * @author wangfeng
 * @since 2024-06-13
 */
@Slf4j
@Service
public class PendingNodeQueueServiceImpl extends ServiceImpl<PendingNodeQueueMapper, PendingNodeQueueModel> implements PendingNodeQueueService {

    @Autowired
    private PendingNodeQueueMapper pendingNodeQueueMapper;

    @Autowired
    private ProcessNodeExampleService processNodeExampleService;

    @Autowired
    private VariableExampleService variableExampleService;

    @Autowired
    private ProcessNodeParamExampleService processNodeParamExampleService;

    @Override
    public void add(Long processNodeExampleId) {
        ProcessNodeExampleModel processNodeExampleModel = processNodeExampleService.getById(processNodeExampleId);
        PendingNodeQueueModel pendingNodeQueueModel = new PendingNodeQueueModel();
        pendingNodeQueueModel.setProcessNodeExampleId(processNodeExampleId);
        pendingNodeQueueModel.setNodeName(processNodeExampleModel.getNodeName());
        pendingNodeQueueModel.setCreateTime(new Date());
        pendingNodeQueueMapper.insert(pendingNodeQueueModel);

    }

    @Override
    public void backgroundRunPendingNode() {
        List<PendingNodeQueueModel> pendingNodeQueueModels = pendingNodeQueueMapper.selectList(null);
        for (PendingNodeQueueModel pendingNodeQueueModel : pendingNodeQueueModels) {
            Long id = pendingNodeQueueModel.getId();
            String nodeName = pendingNodeQueueModel.getNodeName();
            ProcessNodeExampleModel processNodeExampleModel = processNodeExampleService.getById(pendingNodeQueueModel.getProcessNodeExampleId());
            if (ObjectUtils.isEmpty(processNodeExampleModel)) {
                pendingNodeQueueMapper.deleteById(id);
            }
            if (nodeName.equals(ProcessNodeNameEnum.DELAY.getNodeName())) {
                executeDelay(pendingNodeQueueModel, processNodeExampleModel);
            }
            if (nodeName.equals(ProcessNodeNameEnum.WAIT_FOR.getNodeName())) {
                executeWaitFor(pendingNodeQueueModel, processNodeExampleModel);
            }
            if (nodeName.equals(ProcessNodeNameEnum.CONFIRM.getNodeName())) {
                executeConfirm(pendingNodeQueueModel, processNodeExampleModel);
            }
        }
    }


    private void executeDelay(PendingNodeQueueModel pendingNodeQueueModel, ProcessNodeExampleModel processNodeExampleModel) {
        // 判断delay时间时间超过当前时间
        long currentTimeMillis = System.currentTimeMillis();
        Long processNodeExampleId = processNodeExampleModel.getId();
        Map<String, ProcessNodeParamExampleModel> processNodeParam = processNodeParamExampleService.getProcessNodeParam(processNodeExampleId);
        log.info("processNodeExampleId:{},executeDelay processNodeParam : {}", processNodeExampleId, JSONObject.toJSONString(processNodeParam));
        // 获取delay的延时时间
        ProcessNodeParamExampleModel processNodeParamExampleModel = processNodeParam.get(NodeParamConstant.DELAY.delaySecond);
        String value = processNodeParamExampleModel.getValue();
        Long delaySecond = Long.parseLong(value);
        Date date = DateUtils.dateAddSecond(pendingNodeQueueModel.getCreateTime(), delaySecond);
        long delayTimeMillis = date.getTime();
        log.debug("executeDelay,{}->{}", currentTimeMillis, delayTimeMillis);
        if (currentTimeMillis >= delayTimeMillis) {
            log.debug("满足需求运行delay");
            // delay节点变成完成状态
            processNodeExampleService.updateNodeStatus(processNodeExampleId, TaskStatusEnum.SUCCESS.getStatus());
            // 运行下一个节点
            processNodeExampleService.runNextNode(processNodeExampleId);
            pendingNodeQueueMapper.deleteById(pendingNodeQueueModel.getId());
        }
    }

    private void executeWaitFor(PendingNodeQueueModel pendingNodeQueueModel, ProcessNodeExampleModel processNodeExampleModel) {
        Long processNodeExampleId = processNodeExampleModel.getId();
        Map<String, ProcessNodeParamExampleModel> processNodeParam = processNodeParamExampleService.getProcessNodeParam(processNodeExampleId);
        ProcessNodeParamExampleModel conditionVariable = processNodeParam.get("conditionVariable");
        ProcessNodeParamExampleModel conditionValue = processNodeParam.get("conditionValue");
        VariableExampleValueResp variableExampleModel2 = variableExampleService.getByNameExt(processNodeExampleModel.getId(), conditionVariable.getValue());
        String variableValue = variableExampleModel2.getCurrentValue();
        log.debug("executeWaitFor variableName:{}，variableValue：{}", conditionVariable.getName(), variableValue);
        if (variableValue.equals(conditionValue.getValue())) {
            log.debug("满足需求运行WaitFor");
            // delay节点变成完成状态
            processNodeExampleService.updateNodeStatus(processNodeExampleId, TaskStatusEnum.SUCCESS.getStatus());
            // 运行下一个节点
            processNodeExampleService.runNextNode(processNodeExampleId);
            pendingNodeQueueMapper.deleteById(pendingNodeQueueModel.getId());
        }
    }

    private void executeConfirm(PendingNodeQueueModel pendingNodeQueueModel, ProcessNodeExampleModel processNodeExampleModel) {
        Long processNodeExampleId = processNodeExampleModel.getId();
        Map<String, ProcessNodeParamExampleModel> processNodeParam = processNodeParamExampleService.getProcessNodeParam(processNodeExampleId);
        ProcessNodeParamExampleModel conditionValue = processNodeParam.get(NodeParamConstant.CONFIRM.conditionValue);
        log.debug("executeConfirm conditionVariable：{}", conditionValue);
        String value = conditionValue.getValue();
        int condition = Integer.parseInt(value);
        if (condition == 1) {
            log.debug("满足需求运行confirm");
            // confirm节点变成完成状态
            processNodeExampleService.updateNodeStatus(processNodeExampleId, TaskStatusEnum.SUCCESS.getStatus());
            // 运行下一个节点
            processNodeExampleService.runNextNode(processNodeExampleId);
            pendingNodeQueueMapper.deleteById(pendingNodeQueueModel.getId());
        }
    }
}
